home *** CD-ROM | disk | FTP | other *** search
- PROGRAM Cribbage;
-
- (* TURBO PASCAL 1.0
- Morrow Micro Decision MD-2
- David C. Oshel, Jan 15, 1984, 1219 Harding Ave, Ames, Iowa 50010
- *)
-
-
- { TITLE PAGE:
- (':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
- (':: Adapted from "Cribbage" in APPLE PASCAL GAMES, by Douglas Hergert ::');
- (':: and Joseph T. Kalash, pages 301-349. Sybex, 1981. ::');
- (':: ::');
- (':: January 8, 1984 d.c.o. ::');
- (':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
- }
-
- Label 1;
-
- Const
- decksize = 52;
- dealsize = 6;
- scribsize = 6;
- playsize = 4;
- ranksize = 13;
- winpoints = 121;
-
- Type
- charset = set of char;
- str80 = string[80];
- suitype = (hearts,diamonds,clubs,spades);
- ranktype = 0..ranksize;
-
- card = record
- rank: ranktype;
- suit: suitype
- end;
-
- handtype = array[1..dealsize] of card;
-
- {Typed} Const
-
- alpha:charset = [' '..'}'];
-
- Var
- deck: array[1..decksize] of card;
- comp,
- human,
- crib: handtype;
- common: card;
- i,
- hscore,
- cscore: integer;
- ch: char;
- xplayx: integer;
-
- (*
- This is the code for simulating an Exit with TURBO Pascal 1.0
-
- --> Include this instead of Exit(Procname) in the procedure which
- actually invokes the exit:
-
- inline($2A/save/ { LD HL,(save) ; EXIT PROC }
- $F9); { LD SP,HL }
- goto procend;
-
- --> Include this as the FIRST instruction in the Procedure you wish
- to eventually exit from:
-
- inline($21/0/0/ { LD HL,0000h ; MARK PROC }
- $39/ { ADD HL,SP }
- $22/save); { LD (save),HL }
-
- David C. Oshel, 15 January 1984, Ames, Iowa
- *)
-
-
- function getchar:char;
- var ch,cr,bs: char;
- goodset: charset;
- bailout: boolean;
- begin
- cr:=chr(13); bs:=chr(8); goodset:=alpha+[cr,bs];
- repeat
- read(kbd,ch);
- ch:=upcase(ch);
- bailout:=(ch=chr(3)) or (ch=chr(27));
- if eoln then ch:=cr
- until bailout or (ch in goodset);
- getchar:=ch;
- if bailout then
- inline($2A/xplayx/ { LD HL,(xplayx) ;EXIT PROC }
- $F9) { LD SP,HL }
- end; {getchar}
-
- procedure getln(VAR s:str80);
- var ch: char;
- done: boolean;
- begin
- done:=false;
- s:='';
- repeat
- ch:=getchar;
- if (* bailout or *) (ch=chr(13)) then
- begin
- done:=true;
- writeln
- end
- else if ch=chr(8) then
- begin
- if length(s) > 0 then
- begin
- write(chr(8),' ',chr(8));
- s:=copy(s,1,length(s)-1)
- end
- else s:=''
- end
- else
- begin
- s:=concat(s,ch);
- if ch in alpha then write(ch)
- end
- until done;
- end; {getln}
-
-
- procedure addpoints(who:boolean; amount:integer);
- var winner: boolean;
- begin
- if who then
- begin
- hscore:=hscore+amount;
- writeln('You''ve pegged ',hscore,' points.');
- winner := (hscore >= winpoints)
- end
- else
- begin
- cscore:=cscore+amount;
- writeln('I''ve pegged ',cscore,' points.');
- winner := (cscore >= winpoints)
- end;
- if winner then
- inline($2A/xplayx/ { LD HL,(xplayx) ;EXIT PROC }
- $F9) { LD SP,HL }
- end; {addpoints}
-
- {$I Cribbage.PS2}
-
-
- function getelement:integer;
- label retry;
- var irank,isuit: char;
- rank: ranktype;
- suit: suitype;
- which: integer;
- index: 1..dealsize;
- many: -5..4;
-
- procedure getcard(VAR rankchar:char; VAR suitchar:char);
- var ch: char;
- s: str80;
- i: integer;
- begin
- repeat
- write('__',chr(8),chr(8));
- getln(s);
- rankchar:=' '; suitchar:=' ';
- for i:=1 to length(s) do
- begin
- ch:=s[i];
- if (ch in ['A','2'..'9','T','J','Q','K']) then rankchar:=ch;
- if (ch in ['S','H','D','C']) then suitchar:=ch
- end;
- if (rankchar=' ') or (suitchar=' ') then
- begin
- writeln(s,'?');
- writeln('Suits = S,H,D,C (Spades,Hearts,Diamonds,Clubs)');
- writeln('Ranks = A,2,3,4,5,6,7,8,9,T,J,Q,K (Ace is A, 10 is T!)');
- writeln('Example: 8D (eight of Diamonds) or TH (ten of Hearts)');
- writeln;
- write('Try again from the start. Which card? ')
- end
- until (rankchar<>' ') and (suitchar<>' ');
- writeln('{{{ ',rankchar,suitchar,' }}}');
- end; {getcard}
-
- begin
- retry:
- getcard(irank,isuit);
- case irank of
- 'A': rank:=1;
- '2','3','4','5','6','7','8','9': rank:=ord(irank)-ord('0');
- 'T': rank:=10;
- 'J': rank:=11;
- 'Q': rank:=12;
- 'K': rank:=13
- end; {case}
- case isuit of
- 'S': suit := spades;
- 'H': suit := hearts;
- 'D': suit := diamonds;
- 'C': suit := clubs
- end; {case}
- many:=0;
- which:=0;
- for index:=1 to dealsize do
- begin
- if human[index].rank = rank then
- begin
- many:=many+1;
- if many>0 then which:=index;
- if isuit<>' ' then
- if human[index].suit = suit then
- many:=-5
- end
- end;
- if many=0 then
- begin
- writeln('What?! No such card exists.');
- write('Which card? ');
- goto retry
- end;
- if many>1 then
- begin
- writeln('There is more than one ',irank);
- write('Please be more specific: ');
- goto retry
- end;
- if (many=1) or (many<0) then getelement:=which;
- end; {getelement}
-
- procedure tocrib;
- var cardnum: 1..dealsize;
- numgone: 0..1;
-
- begin
- for numgone:=0 to 1 do
- begin
- write('Throw which card? [ ');
- for cardnum:=1 to (dealsize-numgone) do showcard(human[cardnum]);
- write(' ] ');
- cardnum:=getelement;
- crib[numgone+1]:=human[cardnum];
- while cardnum <= (dealsize-1) do
- begin
- human[cardnum]:=human[cardnum+1];
- cardnum:=cardnum+1
- end;
- human[cardnum].rank:=0
- end;
- end; {tocrib}
-
- procedure sort(n:integer; var hand:handtype);
- var
- touched: boolean;
- index: 1..dealsize;
- tmp: card;
-
- begin
- repeat
- touched:=false;
- for index:=1 to (n-1) do
- if hand[index].rank > hand[index+1].rank then
- begin
- tmp:=hand[index];
- hand[index]:=hand[index+1];
- hand[index+1]:=tmp;
- touched:=true
- end
- until not touched;
- end; {sort}
-
- {$I Cribbage.PS3}
-
- procedure compcrib;
- type
- bestrec = record
- points: integer;
- first, second: 1..dealsize
- end;
- var
- tmp: handtype;
- best: bestrec;
- i,j,points: integer;
-
- function compscore:integer;
- var
- index,points: integer;
- num: 1..dealsize;
- begin
- num:=1;
- for index:=1 to (i-1) do
- begin
- tmp[num]:=comp[index];
- num:=num+1
- end;
- for index:=(i+1) to (j-1) do
- begin
- tmp[num]:=comp[index];
- num:=num+1
- end;
- for index:=(j+1) to dealsize do
- begin
- tmp[num]:=comp[index];
- num:=num+1
- end;
- tmp[5].rank:=0;
- compscore:=score(tmp);
- end; {function compscore}
-
- begin {compcrib}
- best.points:=-1;
- sort(6,comp);
- for i:=1 to (dealsize-1) do
- for j:=i+1 to dealsize do
- begin
- points:=compscore;
- if points > best.points then
- begin
- best.points:=points;
- best.first:=i;
- best.second:=j
- end
- end;
- j:=1;
- for i:=1 to (best.first-1) do
- begin
- tmp[j]:=comp[i];
- j:=j+1
- end;
- for i:=(best.first+1) to (best.second-1) do
- begin
- tmp[j]:=comp[i];
- j:=j+1
- end;
- for i:=(best.second+1) to dealsize do
- begin
- tmp[j]:=comp[i];
- j:=j+1
- end;
- crib[3]:=comp[best.first];
- crib[4]:=comp[best.second];
- for i:=1 to playsize do comp[i]:=tmp[i];
- end; {compcrib}
-
-
- procedure count(who: boolean);
- var
- oldhuman: array[1..4] of card;
- curcount: integer;
- humcant,
- compcant: boolean;
- cnthand: array[1..8] of card;
- last: 0..2;
- cntnum: 1..8;
- lastcnt: integer;
- humleft,
- comleft: 0..playsize;
- i: -1..playsize;
- points: integer;
-
- function countscore(newcard: card):integer;
- var
- return: integer;
- matched, index: 0..8;
- begin
- return:=0; matched:=0;
- cnthand[cntnum]:=newcard;
- if cnthand[cntnum].rank > 10
- then curcount:=curcount+10
- else curcount:=curcount+cnthand[cntnum].rank;
- if cntnum=1 then
- begin
- cntnum:=cntnum+1;
- countscore:=0
- end
- else
- begin
- if (curcount=15) or (curcount=31) then return:=2;
- index:=cntnum;
- while index >= 2 do
- begin
- if cnthand[index].rank=cnthand[index-1].rank then
- matched:=matched+1
- else index:=1;
- index:=index-1
- end;
- case matched of
- 0: ;
- 1: return:=return+2;
- 2: return:=return+6;
- 3: return:=return+12
- end; {case}
- matched:=0;
- index:=cntnum;
- while index >= 2 do
- begin
- if cnthand[index].rank=(cnthand[index-1].rank -1) then
- matched:=matched+1
- else index:=1;
- index:=index-1
- end;
- cntnum:=cntnum+1;
- if matched > 2 then return:=return+matched+1;
- countscore:=return
- end;
- end; {countscore}
-
- function humplay:integer;
- var i,j: integer;
- begin
- if human[1].rank > 10 then i:=10
- else i:=human[1].rank;
- if (humleft <= 0) or ((i+curcount) > 31) then
- begin
- humcant:=true;
- humplay:=-1
- end
- else
- begin
- last:=1;
- humcant:=false;
- if human[2].rank > 10 then i:=10
- else i:=human[2].rank;
- if (humleft=1) or ((i+curcount) > 31) then
- humplay:=1
- else
- begin
- j:=0;
- while j=0 do
- begin
- write('Play which card? [ ');
- for i:=1 to playsize do
- if human[i].rank <> 0 then showcard(human[i]);
- write(' ] ');
- i:=getelement;
- if human[i].rank > 10 then j:=10
- else j:=human[i].rank;
- if (j+curcount) > 31 then
- begin
- writeln('Sorry, that''s more than 31');
- j:=0
- end
- end;
- humplay:=i
- end
- end
- end; {humplay}
-
- function complay:integer;
- var
- index: 1..playsize;
- points, best: integer;
- tmp: 0..10;
- return: 1..playsize;
- begin
- best:=-1;
- if comp[1].rank > 10 then tmp:=10
- else tmp:=comp[1].rank;
- if (comleft=0) or ((tmp+curcount) > 31) then
- begin
- compcant:=true;
- complay:=-1
- end
- else
- begin
- compcant:=false;
- last:=2;
- for index:=1 to comleft do
- begin
- if comp[index].rank>10 then tmp:=10
- else tmp:=comp[index].rank;
- if (tmp<>0) and ((tmp+curcount) <= 31) then
- begin
- points:=countscore(comp[index]);
- cntnum:=cntnum-1;
- curcount:=curcount-tmp;
- if points>best then
- begin
- best:=points;
- return:=index
- end
- end
- end;
- complay:=return
- end;
- end; {complay}
-
- begin {count -- at last!}
- humleft:=playsize;
- comleft:=playsize;
- humcant:=false;
- compcant:=false;
- last:=0;
- cntnum:=1;
- if common.rank=11 then
- begin
- if who then
- begin
- writeln('I get a point for His Nibs!');
- addpoints(false,1);
- end
- else
- begin
- writeln('YOU get a point for His Nibs!!');
- addpoints(true,1);
- end
- end;
- for curcount:=1 to playsize do
- oldhuman[curcount]:=human[curcount];
- curcount:=0;
- while (humleft > 0) or (comleft > 0) do
- begin
- if who then
- begin
- who:=false;
- i:=humplay;
- if i>0 then
- begin
- write('You played a ');
- showcard(human[i]);
- writeln('.');
- points:=countscore(human[i]);
- if points>0 then
- begin
- writeln('You got ',points,' points');
- addpoints(true,points);
- end;
- while i<=(playsize-1) do
- begin
- human[i]:=human[i+1];
- i:=i+1
- end;
- human[humleft].rank:=0;
- humleft:=humleft-1
- end
- end;
- if not who then
- begin
- who:=true;
- i:=complay;
- if i>0 then
- begin
- write('I play a ');
- showcard(comp[i]);
- writeln('.');
- points:=countscore(comp[i]);
- if points>0 then
- begin
- writeln('I got ',points,' points.');
- addpoints(false,points);
- end;
- while i <= (playsize-1) do
- begin
- comp[i]:=comp[i+1];
- i:=i+1
- end;
- comp[comleft].rank:=0;
- comleft:=comleft-1
- end
- end;
- if lastcnt<>curcount then writeln('Total is ',curcount,'.');
- lastcnt:=curcount;
- if (humcant and compcant) or ((humleft=0) and (comleft=0)) then
- begin
- case last of
- 0: ;
- 1: begin
- writeln('You got a point for last card.');
- addpoints(true,1);
- who:=false
- end;
- 2: begin
- writeln('I got a point for last card.');
- addpoints(false,1);
- who:=true
- end
- end; {case}
- writeln;
- writeln('Total is now 0.');
- writeln;
- humcant:=false;
- compcant:=false;
- last:=0;
- cntnum:=1;
- curcount:=0
- end;
- end;
- for curcount:=1 to playsize do
- human[curcount]:=oldhuman[curcount];
- end; {count}
-
-
- procedure play(who: boolean);
- var
- cpoints,
- hpoints,
- crbpnts: integer;
- user:str80;
- usernum,code: integer;
-
- procedure check(num: integer; question: str80);
- begin
- repeat
- write(question);
- getln(user);
- val(user,usernum,code);
- if code<>0
- then writeln(user,'??')
- else writeln;
- until code=0;
- if usernum<>num then
- begin
- writeln('Unless there''s a bug in my program, you should have taken ',num,' points!');
- writeln('I get ',abs(num-usernum),', regardless!');
- addpoints(false,abs(num-usernum));
- if usernum>num then usernum:=num
- end;
- if (usernum > 0) then addpoints(true,usernum);
- writeln;
- end; {check}
-
- begin {play}
- inline($21/0/0/ { LD HL,0000h ; MARK PROC }
- $39/ { ADD HL,SP ; FOR EXIT }
- $22/xplayx); { LD (xplayx),HL }
-
- repeat { forever -- we get out by simulating an Exit(Play) }
- shuffle;
- deal;
- if who then writeln('It''s my crib.')
- else writeln('It''s your crib.');
- sort(6,human);
- tocrib;
- compcrib;
- sort(4,crib);
- if who then
- begin
- repeat
- write('Cut which card [1-40] ? ');
- getln(user);
- val(user,usernum,code);
- if code<>0
- then writeln(user,'??')
- else writeln
- until (code=0) and (usernum in [1..40]);
- common:=deck[usernum+12]
- end
- else
- begin
- common:=deck[13+random(40)]
- end;
- write('The UPCARD is ');
- showcard(common);
- writeln;
- cpoints:=score(comp);
- hpoints:=score(human);
- crbpnts:=score(crib);
- writeln;
- count(who);
- writeln;
- if who then
- begin
- write('[ ');
- for usernum:=1 to playsize do showcard(human[usernum]);
- write(' ] [ ');
- showcard(common);
- writeln(' ]');
- check(hpoints,'How many points you got? ');
- writeln('I''ve got ',cpoints,' points in my hand');
- addpoints(false,cpoints);
- writeln('I have ',crbpnts,' points in my crib');
- addpoints(false,crbpnts);
- end
- else
- begin
- writeln('I''ve got ',cpoints,' in my hand');
- addpoints(false,cpoints);
- writeln;
- write('[ ');
- for usernum := 1 to playsize do showcard(human[usernum]);
- write(' ] [ ');
- showcard(common);
- writeln(' ]');
- check(hpoints,'How many points in YOUR hand? ');
- writeln;
- write('[ ');
- for usernum:=1 to playsize do showcard(crib[usernum]);
- write(' ] [ ');
- showcard(common);
- writeln(' ]');
- check(crbpnts,'How much in the crib? ');
- end;
- who:=not who
- until false
- end; {play}
-
-
- BEGIN {MAIN}
- 1:
- clrscr;
- writeln(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
- writeln(':: W E L C O M E TO K I D D I E K R I B B A G E ! ::');
- writeln(':: ::');
- writeln(':: Adapted from "Cribbage" in APPLE PASCAL GAMES, by Douglas Hergert ::');
- writeln(':: and Joseph T. Kalash, pages 301-349. Sybex, 1981. ::');
- writeln(':: ::');
- writeln(':: TURBO Pascal 1.0, Copyright 1983 by Borland Intl. 1/17/84 DCO ::');
- writeln(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
- writeln;
- writeln('It''s you against me, kid! Whoever pegs 121 points first wins!');
- writeln;
-
- randomize;
- makedeck;
- hscore:=0;
- cscore:=0;
- play(random(2)=0);
-
- writeln;
- if cscore>hscore
- then writeln('Ho Ho!! I peg out and win this game!')
- else writeln('You pegged out and won the game! Congratulations!');
-
- writeln; writeln; writeln;
- write('Do you want another game? ');
- read(kbd,ch); writeln(ch);
- if ch in ['n','N']
- then writeln('OK, see you later!')
- else goto 1
- END.